// Package sys
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2025 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.15.11
package sys

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/gogf/gf/v2/errors/gcode"
	"hotgo/internal/consts"
	"hotgo/internal/dao"
	"hotgo/internal/library/contexts"
	"hotgo/internal/library/hgorm"
	"hotgo/internal/library/hgorm/handler"
	"hotgo/internal/model/entity"
	"hotgo/internal/model/input/form"
	"hotgo/internal/model/input/sysin"
	"hotgo/internal/service"
	"hotgo/utility/convert"
	"hotgo/utility/excel"
	"hotgo/utility/validate"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gconv"
)

type sSysStoreMember struct{}

func NewSysStoreMember() *sSysStoreMember {
	return &sSysStoreMember{}
}

func init() {
	service.RegisterSysStoreMember(NewSysStoreMember())
}

// Model 门店账号管理ORM模型
func (s *sSysStoreMember) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
	return handler.Model(dao.StoreMember.Ctx(ctx), option...)
}

// List 获取门店账号管理列表
func (s *sSysStoreMember) List(ctx context.Context, in *sysin.StoreMemberListInp) (list []*sysin.StoreMemberListModel, totalCount int, err error) {

	list = make([]*sysin.StoreMemberListModel, 0)

	mod := s.Model(ctx, &handler.Option{FilterAuth: false})

	// 字段过滤
	mod = mod.FieldsPrefix(dao.StoreMember.Table(), sysin.StoreMemberListModel{})
	mod = mod.Fields(hgorm.JoinFields(ctx, sysin.StoreMemberListModel{}, &dao.AdminMember, "adminMember"))
	mod = mod.Fields(hgorm.JoinFields(ctx, sysin.StoreMemberListModel{}, &dao.Store, "store"))

	// 关联表字段
	mod = mod.LeftJoinOnFields(dao.AdminMember.Table(), dao.StoreMember.Columns().MemberId, "=", dao.AdminMember.Columns().Id)
	mod = mod.LeftJoinOnFields(dao.Store.Table(), dao.StoreMember.Columns().StoreId, "=", dao.Store.Columns().Id)

	// 查询id
	if in.Id > 0 {
		mod = mod.Where(dao.StoreMember.Columns().Id, in.Id)
	}

	// 查询是否是管理员
	if in.IsAdmin > 0 {
		if in.IsAdmin == 1 {
			mod = mod.Where(dao.StoreMember.Columns().IsAdmin, true)
		} else {
			mod = mod.Where(dao.StoreMember.Columns().IsAdmin, false)
		}
	}

	// 查询创建时间
	if len(in.CreatedAt) == 2 {
		mod = mod.WhereBetween(dao.StoreMember.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
	}

	// 查询真实姓名
	if in.AdminMemberRealName != "" {
		mod = mod.WherePrefixLike(dao.AdminMember.Table(), dao.AdminMember.Columns().RealName, "%"+in.AdminMemberRealName+"%")
	}

	// 查询帐号
	if in.AdminMemberUsername != "" {
		mod = mod.WherePrefixLike(dao.AdminMember.Table(), dao.AdminMember.Columns().Username, "%"+in.AdminMemberUsername+"%")
	}

	// 查询手机号码
	if in.AdminMemberMobile != "" {
		mod = mod.WherePrefixLike(dao.AdminMember.Table(), dao.AdminMember.Columns().Mobile, "%"+in.AdminMemberMobile+"%")
	}

	// 查询门店id
	if in.StoreID > 0 {
		mod = mod.Where(dao.StoreMember.Columns().StoreId, in.StoreID)
	}

	// 查询门店名称
	if in.StoreName != "" {
		mod = mod.WherePrefixLike(dao.Store.Table(), dao.Store.Columns().Name, "%"+in.StoreName+"%")
	}

	// 查询门店电话
	if in.StorePhone != "" {
		mod = mod.WherePrefixLike(dao.Store.Table(), dao.Store.Columns().Phone, "%"+in.StorePhone+"%")
	}

	if in.MemberId > 0 {
		mod = mod.Where(dao.StoreMember.Columns().MemberId, in.MemberId)
	}

	// 分页
	if in.Pagination {
		mod = mod.Page(in.Page, in.PerPage)
	}

	// 排序
	if in.Sorters != nil { // 后台查询
		mod = mod.Handler(handler.Sorter(in))
	} else { // 商户端查询
		mod = mod.OrderDesc(dao.StoreMember.Columns().IsAdmin).Order(dao.StoreMember.Columns().Id)
	}

	// 查询数据
	if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
		err = gerror.Wrap(err, "获取门店账号管理列表失败，请稍后重试！")
		return
	}
	return
}

// Export 导出门店账号管理
func (s *sSysStoreMember) Export(ctx context.Context, in *sysin.StoreMemberListInp) (err error) {
	list, totalCount, err := s.List(ctx, in)
	if err != nil {
		return
	}

	// 字段的排序是依据tags的字段顺序，如果你不想使用默认的排序方式，可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
	tags, err := convert.GetEntityDescTags(sysin.StoreMemberExportModel{})
	if err != nil {
		return
	}

	var (
		fileName  = "导出门店账号管理-" + gctx.CtxId(ctx)
		sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
		exports   []sysin.StoreMemberExportModel
	)

	if err = gconv.Scan(list, &exports); err != nil {
		return
	}

	err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
	return
}

// Edit 修改/新增门店账号管理
func (s *sSysStoreMember) Edit(ctx context.Context, in *sysin.StoreMemberEditInp) (err error) {
	return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {

		// 修改
		if in.Id > 0 {
			if _, err = s.Model(ctx).
				Fields(sysin.StoreMemberUpdateFields{}).
				WherePri(in.Id).Data(in).Update(); err != nil {
				err = gerror.Wrap(err, "修改门店账号管理失败，请稍后重试！")
			}
			return
		}

		// 新增
		if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
			Fields(sysin.StoreMemberInsertFields{}).
			Data(in).OmitEmptyData().Insert(); err != nil {
			err = gerror.Wrap(err, "新增门店账号管理失败，请稍后重试！")
		}
		return
	})
}

// Delete 删除门店账号管理
func (s *sSysStoreMember) Delete(ctx context.Context, in *sysin.StoreMemberDeleteInp) (err error) {
	if contexts.GetRoleId(ctx) != consts.RoleSuper && contexts.GetRoleId(ctx) != consts.RoleManage &&
		contexts.GetRoleId(ctx) != consts.RoleStore {
		err = gerror.NewCode(gcode.CodeInvalidRequest, "没有权限操作")
		return
	}
	if contexts.GetRoleId(ctx) == consts.RoleStore {
		userId := contexts.GetUserId(ctx)
		var storeMember entity.StoreMember
		if err = dao.StoreMember.Ctx(ctx).Where(dao.StoreMember.Columns().IsAdmin, 1).
			Where(dao.StoreMember.Columns().MemberId, userId).Scan(&storeMember); err != nil {
			return gerror.NewCode(gcode.CodeInvalidRequest, "您不是用户所在门店的管理员，不能删除！")
		}
		var delMember entity.StoreMember
		if err = dao.StoreMember.Ctx(ctx).Where(dao.StoreMember.Columns().Id, in.Id).Scan(&delMember); err != nil {
			return gerror.NewCode(gcode.CodeInvalidRequest, "门店成员不存在")
		}
		if delMember.MemberId == userId {
			return gerror.NewCode(gcode.CodeInvalidRequest, "不能删除自己！")
		}
		if delMember.IsAdmin == 1 {
			return gerror.NewCode(gcode.CodeInvalidRequest, "不能删除管理员！")
		}
		if delMember.StoreId != storeMember.StoreId {
			return gerror.NewCode(gcode.CodeInvalidRequest, "您没有权限删除该成员！")
		}
	}
	if _, err = s.Model(ctx).WherePri(in.Id).Unscoped().Delete(); err != nil {
		err = gerror.Wrap(err, "删除门店账号管理失败，请稍后重试！")
		return
	}
	return
}

// View 获取门店账号管理指定信息
func (s *sSysStoreMember) View(ctx context.Context, in *sysin.StoreMemberViewInp) (res *sysin.StoreMemberViewModel, err error) {
	if err = s.Model(ctx).WherePri(in.Id).Scan(&res); err != nil {
		err = gerror.Wrap(err, "获取门店账号管理信息，请稍后重试！")
		return
	}
	return
}

func (s *sSysStoreMember) ViewPhone(ctx context.Context, phone string) (res *sysin.StoreMemberViewModel, err error) {
	mod := s.Model(ctx)
	// 字段过滤
	mod = mod.FieldsPrefix(dao.StoreMember.Table(), sysin.StoreMemberViewModel{})
	mod = mod.Fields(hgorm.JoinFields(ctx, sysin.StoreMemberViewModel{}, &dao.AdminMember, "adminMember"))
	mod = mod.Fields(hgorm.JoinFields(ctx, sysin.StoreMemberViewModel{}, &dao.Store, "store"))

	// 关联表字段
	mod = mod.LeftJoinOnFields(dao.AdminMember.Table(), dao.StoreMember.Columns().MemberId, "=", dao.AdminMember.Columns().Id)
	mod = mod.LeftJoinOnFields(dao.Store.Table(), dao.StoreMember.Columns().StoreId, "=", dao.Store.Columns().Id)
	// 查询手机号码
	if err = mod.WherePrefix(dao.AdminMember.Table(), dao.AdminMember.Columns().Mobile, phone).Scan(&res); err != nil {
		err = gerror.Wrap(err, "获取门店账号管理信息，请稍后重试！")
		return
	}
	return
}

// Switch 更新门店账号管理开关
func (s *sSysStoreMember) Switch(ctx context.Context, in *sysin.StoreMemberSwitchInp) (err error) {
	var fields = []string{
		dao.StoreMember.Columns().IsAdmin,
		// ...
	}

	if !validate.InSlice(fields, in.Key) {
		err = gerror.New("开关键名不在白名单")
		return
	}

	if _, err = s.Model(ctx).WherePri(in.Id).Data(g.Map{
		in.Key: in.Value,
	}).Update(); err != nil {
		err = gerror.Wrap(err, "更新门店账号管理开关失败，请稍后重试！")
		return
	}
	return
}

// StoreApiGetStoreByPhone 获取门店账号管理列表
func (s *sSysStoreMember) StoreApiGetStoreByPhone(ctx context.Context, pageInfo form.PageReq) (list []*sysin.StoreMemberListModel, totalCount int, err error) {
	user := contexts.GetUser(ctx)
	return s.List(ctx, &sysin.StoreMemberListInp{
		PageReq:  pageInfo,
		MemberId: user.Id,
		//StorePhone: user.Mobile,
	})
}

// 管理权限验证
func (s *sSysStoreMember) StorePermission(ctx context.Context, in *sysin.StorePermissionInp) (bool, error) {

	mod := s.Model(ctx)

	mod = mod.
		Where(dao.StoreMember.Columns().StoreId, in.StoreId).
		Where(dao.StoreMember.Columns().MemberId, contexts.GetUserId(ctx))

	if in.IsAdmin == 1 {
		mod = mod.Where(dao.StoreMember.Columns().IsAdmin, 1)
	}

	return mod.Exist()
}

// 数据板块
func (s *sSysStoreMember) StoreData(ctx context.Context, in *sysin.StoreDataInp) (res *sysin.StoreDataModel, err error) {

	// 门店信息
	store := new(entity.Store)
	err = dao.Store.Ctx(ctx).WherePri(in.StoreId).Scan(&store)
	if err == sql.ErrNoRows {
		return nil, gerror.Wrap(err, "门店不存在")
	} else if err != nil {
		return nil, gerror.Wrap(err, "获取门店信息，请稍后重试！")
	}

	// 条件
	arg := fmt.Sprintf("store_id = %d", store.Id)
	if store.BusinessId > 0 {
		arg = fmt.Sprintf("business_id = %d", store.BusinessId)
	}

	// 获取数据
	err = g.DB().Raw(fmt.Sprintf(`
	SELECT 
	
		-- 团购流水 - 总流水
		(SELECT COALESCE(SUM(hg_product.cost_price * hg_order.qty), 0) 
		 FROM hg_order 
		 LEFT JOIN hg_product ON (hg_order.product_id = hg_product.id)
		 WHERE hg_order.order_type = '团购订单' 
		   AND hg_order.%s
		   AND hg_order.status = '已完成') AS total_group_buy_revenue,
			
		-- 团购流水 - 今日流水
		(SELECT COALESCE(SUM(hg_product.cost_price * hg_order.qty), 0) 
		 FROM hg_order 
		 LEFT JOIN hg_product ON (hg_order.product_id = hg_product.id)
		 WHERE hg_order.order_type = '团购订单' 
		   AND hg_order.%s
		   AND hg_order.status = '已完成'
		   AND DATE(hg_order.created_at) = CURDATE()) AS today_group_buy_revenue,

		-- 团购销量 - 总销量
		(SELECT COALESCE(SUM(qty), 0) 
		 FROM hg_order 
		 WHERE order_type = '团购订单' 
		   AND %s
		   AND status IN ('已完成','待核销')) AS total_group_buy_quantity,
			 
		-- 团购销量 - 今日销量
		(SELECT COALESCE(SUM(qty), 0) 
		 FROM hg_order 
		 WHERE order_type = '团购订单' 
		   AND %s
		   AND status IN ('已完成','待核销')
		   AND DATE(created_at) = CURDATE()) AS today_group_buy_quantity,
			 
		-- 会员销售 - 总销量
		(SELECT COALESCE(SUM(qty), 0) 
		 FROM hg_order 
		 WHERE order_type = '会员订单'
		   AND %s
		   AND status = '已完成') AS total_member_sales_quantity,
			 
		-- 会员销售 - 今日销量
		(SELECT COALESCE(SUM(qty), 0) 
		 FROM hg_order 
		 WHERE order_type = '会员订单' 
		   AND %s
		   AND status = '已完成'
		   AND DATE(created_at) = CURDATE()) AS today_member_sales_quantity,
			 
		-- 权益核销 - 总核销次数
		(SELECT COALESCE(SUM(count), 0) 
		 FROM hg_order_verify_log 
		 WHERE %s) AS total_redemption_count,
			 
		-- 权益核销 - 今日核销次数
		(SELECT COALESCE(SUM(count), 0) 
		 FROM hg_order_verify_log 
		 WHERE %s
		   AND DATE(created_at) = CURDATE()) AS today_redemption_count
	`, arg, arg, arg, arg, arg, arg, arg, arg)).Scan(&res)

	// TODO 会员流水-总金额、今日数据 在有分销数据后添加

	if err != nil {
		return nil, err
	}

	// 总流水 = 团购流水 + 会员流水
	res.TotalRevenue = res.TotalGroupBuyRevenue + res.TotalMemberRevenue
	return res, nil
}
